<?php
/**
 * Each engineer has a duty to keep the code elegant
 * Created by wolffy.
 * Author @wolffy<13750088090@sina.cn>
 * Date: 2018/8/11
 * Time: 11:54
 */
namespace App\Services;

use App\Handlers\ApiResponse;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
use Laravel\Passport\Token;

class PassportService
{
    use ApiResponse;

    use AuthenticatesUsers;

    public function authUserToLogin(Request $request)
    {
        $validator = $this->loginValidator($request->all());
        if ($validator->fails()) {
            $errors = $validator->errors()->messages();
            $error = "";
            foreach ($errors as $key=>$value) {
                $error = $value[0];
                break;
            }
            return $this->responseJson(422, [], false, $error, '检查手机号码是否注册或输错数字');
        }
        $credentials = $this->credentials($request);
        if ($this->guard('api')->attempt($credentials)) {
            $response = $this->sendLoginResponse($request);
            $json = json_decode($response->content(), true);
            if (isset($json['error'])) {
                return $this->responseJson(401, [], false, $json['message']);
            }
            if (empty($json)) {
                return $this->responseJson(400);
            }
            $json['user'] = $request->user();
            $user = $json['user']->toArray();
            if (1 == $user['is_lock']) {
                $this->revokeTokens($user['user_id'], $request->client_id);
                return $this->responseJson(10105);//账号被冻结
            }
            $data = [
                'last_ip' => $request->ip(),
                'last_login' => time(),
                'client_login' => $request->client_id,
                'api_version_number' => !empty($request->header('Api-Version-Number')) ? $request->header('Api-Version-Number') : '',
                'app_version_number' => !empty($request->header('App-Version-Number')) ? $request->header('App-Version-Number') : '',
                'mobile_brand' => !empty($request->header('Mobile-Brand')) ? $request->header('Mobile-Brand') : $request->header('user-agent'),
                'mobile_model' => !empty($request->header('Mobile-Model')) ? $request->header('Mobile-Model') : '',
                'device_no' => !empty($request->header('Device-No')) ? $request->header('Device-No') : '',
                'mac_address' => !empty($request->header('Mac-Address')) ? $request->header('Mac-Address') : '',
            ];
            //更新登录ip和登录时间
            $json['user']->update($data);
            $json['user']['head_pic'] = !empty($json['user']['head_pic']) ? getOssImageUrl($json['user']['head_pic']) : '';
            $json['other']['own_qrcode'] = config('app.url') . '/user/register?invited_code=' . invitedStrtolowerOI($user['invited_code']);
            return $this->responseJson(0, $json, false, 'success', '登录成功');
        }
        return $this->responseJson(10100);
    }

    //调用认证接口获取授权码
    public function authenticateClient(Request $request)
    {
        $credentials = $this->credentials($request);
        $data = $request->all();
        $request->request->add([
            'grant_type' => $data['grant_type'],
            'client_id' => $data['client_id'],
            'client_secret' => $data['client_secret'],
            'username' => $credentials['mobile'],
            'password' => $credentials['password'],
            'scope' => ''
        ]);
        $proxy = $request::create(
            'oauth/token',
            'POST'
        );
        $response = \Route::dispatch($proxy);
        return $response;
    }

    /**
     * Get the needed authorization credentials from the request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function credentials(Request $request)
    {
        return $request->only($this->username(), 'password');
    }

    //以下为重写部分
    public function authenticated(Request $request)
    {
        return $this->authenticateClient($request);
    }

    public function sendLoginResponse(Request $request)
    {
        $this->clearLoginAttempts($request);

        return $this->authenticated($request);
    }

    public function username()
    {
        return 'mobile';
    }

    /**
     * Get the guard to be used during authentication.
     *
     * @return \Illuminate\Contracts\Auth\StatefulGuard
     */
    public function guard()
    {
        return Auth::guard();
    }

    /**
     * 清理access_token 冻结用户不给token
     * @param $userId
     * @param $clientId
     * @return mixed
     */
    protected function revokeTokens($userId, $clientId)
    {
        return Token::where('user_id', $userId)
            ->where('client_id', $clientId)
            ->delete();
    }

    /**
     * 验证登录规则，中文提示信息
     * @param $payload
     * @return mixed
     */
    protected function loginValidator($payload)
    {
        $rules = [
            'grant_type' => 'required',
            'client_id' => 'required',
            'client_secret' => 'required',
            'mobile' => 'required|regex:/^1[3456789]{1}\d{9}$/|exists:users',
            'password'=>'required|min:6',
        ];
        $message = [
            'grant_type.required' => '授权模式',
            'client_id.required' => 'appid不能为空',
            'client_secret.required' => 'appsecret不能为空',
            'mobile.regex' => '手机号码格式不正确',
            'password.required'=>'密码不能为空',
            'password.min'=>'密码至少6位',
        ];
        $validator = Validator::make($payload, $rules, $message);
        return $validator;
    }

    public function userInfo()
    {
        $user = Auth::guard('api')->user();
        if (!empty($user)) {
            $userInfo = $user->toArray();
            $userInfo['head_pic'] = !empty($userInfo['head_pic']) ? getOssImageUrl($userInfo['head_pic']) : '';
        } else {
            $userInfo = [];
        }
        return $userInfo;
    }
}